﻿/*
 * scada.hpp
 *
 *  Created on: 2017年11月21日
 *      Author: work
 */

#ifndef _DM_SCADA_SCADA_HPP_
#define _DM_SCADA_SCADA_HPP_

#include <dm/export.hpp>

#ifndef DM_API_SCADA
#define DM_API_SCADA DM_API_IMPORT
#endif

#include <dm/scada/rtvalue.hpp>
#include <dm/scada/status.hpp>
#include <dm/scada/discrete.hpp>
#include <dm/scada/measure.hpp>
#include <dm/scada/cumulant.hpp>
#include <dm/scada/action.hpp>

#include <dm/os/syswaitqueue.hpp>
#include <dm/scada/event.hpp>
#include <dm/scada/timedmeasure.hpp>
#include <dm/scada/timedcumulant.hpp>

#include <iostream>

namespace dm{
namespace scada{

class DM_API_SCADA CScadaInfo;
struct DM_API_SCADA SDeviceInfo;
struct DM_API_SCADA SStatusInfo;
struct DM_API_SCADA SStatusDescInfo;
struct DM_API_SCADA SDiscreteInfo;
struct DM_API_SCADA SDiscreteDescInfo;
struct DM_API_SCADA SMeasureInfo;
struct DM_API_SCADA SCumulantInfo;
struct DM_API_SCADA SRemoteCtlInfo;
struct DM_API_SCADA SRemoteCtlDescInfo;
struct DM_API_SCADA SParaInfo;
struct DM_API_SCADA SActionInfo;
struct DM_API_SCADA SActionDescInfo;

struct DM_API_SCADA SLogicDeviceInfo;

class DM_API_SCADA CDeviceState;

class DM_API_SCADA CScadaLoader;

/**
 * SCADA基类
 * 其他平台数据访问都应该基于本基类
 */
class DM_API_SCADA CScada{
	CScada();
	CScada& operator=( const CScada& );
protected:
	CScada( CScada& scada );
public:
	enum{
		EventQueueSize = 1024,		//!< 事件队列大小
		MeasureQueueSize = 1024,	//!< 测量量队列大小
		CumulantQueueSize = 1024	//!< 累计量队列大小
	};

	// 实时数据
	typedef TCRtValue<CStatus> status_t;		//!< 实时状态量类型
	typedef TCRtValue<CDiscrete> discrete_t;	//!< 实时离散量类型
	typedef TCRtValue<CMeasure> measure_t;		//!< 实时测量量
	typedef TCRtValue<CCumulant> cumulant_t;	//!< 实时累计量

	typedef dm::os::CSysWaitQueue<CEvent,EventQueueSize> event_queue_t;	//!< 事件队列
	typedef dm::os::CSysWaitQueue<CTimedMeasure,EventQueueSize> measure_queue_t; //!< 测量量队列
	typedef dm::os::CSysWaitQueue<CTimedCumulant,EventQueueSize> cumulant_queue_t; //!< 累计量队列

	static CScada& ins();

	/**
	 * 获取SCADA系统信息
	 */
	inline const CScadaInfo* info()const{
		return m_info;
	}

	/**
	 * 获取设备配置信息列表
	 */
	inline const SDeviceInfo* deviceInfos()const{
		return m_deviceInfos;
	}

	/**
	 * 获取状态量配置信息列表
	 */
	inline const SStatusInfo* statusInfos()const{
		return m_statusInfos;
	}

	/**
	 * 获取状态描述信息列表
	 */
	inline const SStatusDescInfo* statusDescInfos()const{
		return m_statusDescInfos;
	}

	/**
	 * 获取离散量配置信息列表
	 */
	inline const SDiscreteInfo* discreteInfos()const{
		return m_discreteInfos;
	}

	/**
	 * 获取离散量描述信息列表
	 * @return
	 */
	inline const SDiscreteDescInfo* discreteDescInfos()const{
		return m_discreteDescInfos;
	}

	/**
	 * 获取测量量配置信息列表
	 */
	inline const SMeasureInfo* measureInfos()const{
		return m_measureInfos;
	}

	/**
	 * 获取累计量配置信息列表
	 */
	inline const SCumulantInfo* cumulantInfos()const{
		return m_cumulantInfos;
	}

	/**
	 * 获取远控配置信息列表
	 */
	inline const SRemoteCtlInfo* remoteCtlInfos()const{
		return m_remoteCtlInfos;
	}

	/**
	 * 获取远控描述信息列表
	 */
	inline const SRemoteCtlDescInfo* remoteCtlDescInfos()const{
		return m_remoteCtlDescInfos;
	}

	/**
	 * 获取参数配置信息列表
	 */
	inline const SParaInfo* parameterInfos()const{
		return m_parameterInfos;
	}

	/**
	 * 获取动作配置信息列表
	 */
	inline const SActionInfo* actionInfos()const{
		return m_actionInfos;
	}

	/**
	 * 获取动作描述信息
	 */
	inline const SActionDescInfo* actionDescInfos()const{
		return m_actionDescInfos;
	}

	/**
	 * 获取逻辑设备配置信息列表
	 */
	inline const SLogicDeviceInfo* logicDeviceInfos()const{
		return m_logicDeviceInfos;
	}

	/**
	 * 获取到逻辑状态量映射信息列表
	 */
	inline const index_t* map2logicStatuses()const{
		return m_map2logicStatus;
	}

	/**
	 * 获取到逻辑离散量映射信息列表
	 * @return
	 */
	inline const index_t* map2logicDiscretes()const{
		return m_map2logicDiscrete;
	}

	/**
	 * 获取到逻辑测量量映射信息列表
	 * @return
	 */
	inline const index_t* map2logicMeasures()const{
		return m_map2logicMeasure;
	}

	/**
	 * 获取到逻辑累计量映射信息列表
	 * @return
	 */
	inline const index_t* map2logicCumulants()const{
		return m_map2logicCumulant;
	}

	/**
	 * 获取到逻辑远控映射信息列表
	 * @return
	 */
	inline const index_t* map2logicRemoteCtls()const{
		return m_map2logicRemoteCtl;
	}

	/**
	 * 获取到逻辑参数映射信息列表
	 * @return
	 */
	inline const index_t* map2logicParameters()const{
		return m_map2logicParameter;
	}

	/**
	 * 获取到逻辑动作映射信息列表
	 * @return
	 */
	inline const index_t* map2logicActions()const{
		return m_map2logicAction;
	}

	/**
	 * 获取到物理状态量映射信息列表
	 * @return
	 */
	inline const index_t* map2Statuses()const{
		return m_map2Status;
	}

	/**
	 * 获取到物理离散量映射信息列表
	 * @return
	 */
	inline const index_t* map2Discretes()const{
		return m_map2Discrete;
	}

	/**
	 * 获取到物理测量量映射信息列表
	 * @return
	 */
	inline const index_t* map2Measures()const{
		return m_map2Measure;
	}

	/**
	 * 获取到物理累计量映射信息列表
	 * @return
	 */
	inline const index_t* map2Cumulants()const{
		return m_map2Cumulant;
	}

	/**
	 * 获取到物理远控映射信息列表
	 * @return
	 */
	inline const index_t* map2RemoteCtls()const{
		return m_map2RemoteCtl;
	}

	/**
	 * 获取到物理参数映射信息列表
	 * @return
	 */
	inline const index_t* map2Parameters()const{
		return m_map2Parameter;
	}

	/**
	 * 获取到物理动作映射信息列表
	 * @return
	 */
	inline const index_t* map2Actions()const{
		return m_map2Action;
	}

	static void reset();

	/**
	 * 获取物理设备状态列表
	 * @return
	 */
	inline CDeviceState* deviceStates()const{
		return m_deviceStates;
	}

	/**
	 * 获取实时状态量列表
	 * @return
	 */
	inline const status_t* statuses()const{
		return m_statuses;
	}

	/**
	 * 获取实时离散量列表
	 * @return
	 */
	inline const discrete_t* discretes()const{
		return m_discretes;
	}

	/**
	 * 获取实时测量量列表
	 * @return
	 */
	inline const measure_t* measures()const{
		return m_measures;
	}

	/**
	 * 获取实时累计量列表
	 * @return
	 */
	inline const cumulant_t* cumulants()const{
		return m_cumulants;
	}

protected:
	friend class CStatusDescMgr;
	friend class CStatusMgr;
	friend class CDiscreteDescMgr;
	friend class CDiscreteMgr;
	friend class CMeasureMgr;
	friend class CCumulantMgr;
	friend class CRemoteCtlDescMgr;
	friend class CRemoteCtlMgr;
	friend class CParameterMgr;
	friend class CActionDescMgr;
	friend class CActionMgr;
	friend class CDeviceMgr;
	friend class CLogicDeviceMgr;
	friend class CDeviceAgent;

	inline CScadaInfo* info(){
		return m_info;
	}

	inline SDeviceInfo* deviceInfos(){
		return m_deviceInfos;
	}

	inline SStatusInfo* statusInfos(){
		return m_statusInfos;
	}

	inline SStatusDescInfo* statusDescInfos(){
		return m_statusDescInfos;
	}

	inline SDiscreteInfo* discreteInfos(){
		return m_discreteInfos;
	}

	inline SDiscreteDescInfo* discreteDescInfos(){
		return m_discreteDescInfos;
	}

	inline SMeasureInfo* measureInfos(){
		return m_measureInfos;
	}

	inline SCumulantInfo* cumulantInfos(){
		return m_cumulantInfos;
	}

	inline SRemoteCtlInfo* remoteCtlInfos(){
		return m_remoteCtlInfos;
	}

	inline SRemoteCtlDescInfo* remoteCtlDescInfos(){
		return m_remoteCtlDescInfos;
	}

	inline SParaInfo* parameterInfos(){
		return m_parameterInfos;
	}

	inline SActionInfo* actionInfos(){
		return m_actionInfos;
	}


	inline SActionDescInfo* actionDescInfos(){
			return m_actionDescInfos;
	}

	inline SLogicDeviceInfo* logicDeviceInfos(){
		return m_logicDeviceInfos;
	}

	/**
	 * 获取实时状态量列表
	 * @return
	 */
	inline status_t* statuses(){
		return m_statuses;
	}

	/**
	 * 获取实时离散量列表
	 * @return
	 */
	inline discrete_t* discretes(){
		return m_discretes;
	}

	/**
	 * 获取实时测量量列表
	 * @return
	 */
	inline measure_t* measures(){
		return m_measures;
	}

	/**
	 * 获取实时累计量列表
	 * @return
	 */
	inline cumulant_t* cumulants(){
		return m_cumulants;
	}

	/**
	 * 获取事件队列
	 * @return
	 */
	inline event_queue_t* eventQueue(){
		return m_eventQueue;
	}

	/**
	 * 获取测量量队列
	 * @return
	 */
	inline measure_queue_t* measureQueue(){
		return m_measureQueue;
	}

	/**
	 * 获取累计量队列
	 * @return
	 */
	inline cumulant_queue_t* cumulantQueue(){
		return m_cumulantQueue;
	}

private:
	friend class CScadaLoader;

	//! 系统信息
	CScadaInfo* m_info;

	//! 设备信息
	SDeviceInfo* m_deviceInfos;

	//! 各量配置信息
	SStatusInfo* m_statusInfos;
	SStatusDescInfo* m_statusDescInfos;
	SDiscreteInfo* m_discreteInfos;
	SDiscreteDescInfo* m_discreteDescInfos;
	SMeasureInfo* m_measureInfos;
	SCumulantInfo* m_cumulantInfos;
	SRemoteCtlInfo* m_remoteCtlInfos;
	SRemoteCtlDescInfo* m_remoteCtlDescInfos;
	SParaInfo* m_parameterInfos;
	SActionInfo* m_actionInfos;
	SActionDescInfo* m_actionDescInfos;

	//! 逻辑设备信息
	SLogicDeviceInfo* m_logicDeviceInfos;

	/**
	 * @brief 到逻辑设备的映射
	 * 以下定义了物理信号到各逻辑设备的映射
	 * 如果到某逻辑设备的索引无效，表示该逻辑设备不包含该信号
	 * 缓冲区结构
	 * 信号1 [逻辑设备1，逻辑设备2，...，逻辑设备n]
	 * 信号2 [逻辑设备1，逻辑设备2，..., 逻辑设备n]
	 * ...
	 * 信号m [逻辑设备1，逻辑设备2, ..., 逻辑设备n]
	 */
	index_t* m_map2logicStatus;		//!< 状态量到逻辑设备映射表
	index_t* m_map2logicDiscrete;	//!< 离散量到逻辑设备映射表
	index_t* m_map2logicMeasure;	//!< 测量量到逻辑设备映射表
	index_t* m_map2logicCumulant;	//!< 累计量到逻辑设备映射表
	index_t* m_map2logicRemoteCtl;	//!< 远控到逻辑设备映射表
	index_t* m_map2logicParameter;	//!< 参数到逻辑设备映射表
	index_t* m_map2logicAction;		//!< 动作到逻辑设备映射表

	/**
	 * @brief 到物理设备的映射
	 * 
	 * 以下定义了逻辑设备信号到物理信号的映射
	 * 缓冲区结构
	 * 逻辑设备1 [信号1，信号2，...，信号N1]
	 * 逻辑设备2 [信号1, 信号2, ..., 信号N2]
	 * ...
	 * 逻辑设备n [信号1，信号2，..., 信号Nn]
	 */
	index_t* m_map2Status;		//!< 逻辑设备状态量映射表
	index_t* m_map2Discrete;	//!< 逻辑设备离散量映射表
	index_t* m_map2Measure;		//!< 逻辑设备测量量映射表
	index_t* m_map2Cumulant;	//!< 逻辑设备累计量映射表
	index_t* m_map2RemoteCtl;	//!< 逻辑设备远控映射表
	index_t* m_map2Parameter;	//!< 逻辑设备参数映射表
	index_t* m_map2Action;		//!< 逻辑设备动作映射表

	//! 实时数据

	CDeviceState* m_deviceStates;	//! 设备状态

	status_t* m_statuses;
	discrete_t* m_discretes;
	measure_t* m_measures;
	cumulant_t* m_cumulants;

	//! 队列
	event_queue_t* m_eventQueue;
	measure_queue_t* m_measureQueue;
	cumulant_queue_t* m_cumulantQueue;
};

}
}

#endif /* DM_RUNTIME_INCLUDE_DM_SCADA_SCADA_HPP_ */
